/*
 * Copyright (C) 2018 xuexiangjys(xuexiangjys@163.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.xuexiang.xdlinkdemo.device.provider;

import android.content.Context;
import android.support.annotation.NonNull;

import com.xuexiang.xdlink.XDLink;
import com.xuexiang.xdlink.component.channel.IChannel;
import com.xuexiang.xdlink.component.channel.impl.socket.server.MultiServerSocketChannel;
import com.xuexiang.xdlink.component.command.IProtocolCommand;
import com.xuexiang.xdlink.component.message.IDataInfo;
import com.xuexiang.xdlink.core.IDeviceConnectCenter;
import com.xuexiang.xdlink.core.impl.AbstractDeviceDataProvider;
import com.xuexiang.xdlinkdemo.device.Constants;
import com.xuexiang.xdlinkdemo.device.message.server.ServerJsonRequestMessage;
import com.xuexiang.xdlinkdemo.device.protocol.ChatServerProtocol;
import com.xuexiang.xdlinkdemo.device.resolver.ChatServerMessageResolver;
import com.xuexiang.xdlinkdemo.entity.ApiEntity;
import com.xuexiang.xdlinkdemo.entity.ChatMessage;
import com.xuexiang.xdlinkdemo.entity.LoginInfo;
import com.xuexiang.xutil.net.JsonUtil;
import com.xuexiang.xutil.tip.ToastUtils;

import static com.xuexiang.xdlinkdemo.device.Constants.ApiType.LOGIN;
import static com.xuexiang.xdlinkdemo.device.Constants.ApiType.SEND_MESSAGE;
import static com.xuexiang.xdlinkdemo.device.Constants.CHAT_SERVER_PORT;

/**
 * 聊天服务端数据提供者
 *
 * @author xuexiang
 * @since 2018/9/3 下午8:03
 */
public class ChatServerDataProvider extends AbstractDeviceDataProvider {

    private OnChatListener mOnChatListener;

    /**
     * 构造函数
     *
     * @param context
     */
    public ChatServerDataProvider(Context context) {
        super(context);
    }

    public void startServer() {
        initDevice();
        connectDevice();
    }

    public void stopServer() {
        disConnectDevice();
    }

    /**
     * 发送消息
     * @param apiEntity
     */
    public boolean send(@NonNull ApiEntity apiEntity) {
        return sendMessage(new ServerJsonRequestMessage(apiEntity));
    }

    public ChatServerDataProvider setOnChatListener(OnChatListener onChatListener) {
        mOnChatListener = onChatListener;
        return this;
    }

    @Override
    public void onReceivedDataInfo(IDataInfo dataInfo) {
        if (dataInfo instanceof ApiEntity) {
            handleApiEntity((ApiEntity) dataInfo);
        }
    }

    /**
     * 处理接收到的api消息
     * @param apiEntity
     */
    private void handleApiEntity(ApiEntity apiEntity) {
        if (mOnChatListener == null) return;

        switch(apiEntity.getType()) {
            case LOGIN:
                LoginInfo loginInfo = JsonUtil.fromJson(apiEntity.getData().toString(), LoginInfo.class);
                if (loginInfo != null) {
                    handleLogin(loginInfo);
                }
                break;
            case SEND_MESSAGE:
                ChatMessage message = JsonUtil.fromJson(apiEntity.getData().toString(), ChatMessage.class);
                if (message != null) {
                    mOnChatListener.onUpdateChatMessage(message);
                } else {
                    ToastUtils.toast("Json解析失败！");
                }
                break;
            default:
                break;
        }

    }

    private void handleLogin(LoginInfo loginInfo) {
        if (loginInfo.getLoginName().equals("xuexiang") && loginInfo.getPassword().equals("123456")) {
            send(new ApiEntity<Boolean>(LOGIN).setData(true));
            mOnChatListener.onUpdateEvent(LOGIN, true);
        } else {
            send(new ApiEntity<Boolean>(LOGIN).setData(false).setCode(100).setMsg("用户名密码错误！"));
            mOnChatListener.onUpdateEvent(LOGIN, false);
        }
    }

    @NonNull
    @Override
    public IDeviceConnectCenter buildDeviceConnectCenter(Context context) {
        return XDLink.newDevice(Constants.DeviceType.CHAT_CLIENT)
                .setChannel(new MultiServerSocketChannel(CHAT_SERVER_PORT))
                .setResolver(new ChatServerMessageResolver())
                .setProtocol(new ChatServerProtocol())
                .setDeviceListeners(this, this)
                .build();
    }

    @Override
    public IProtocolCommand onChannelConnectStatusChanged(IChannel channel) {
        if (mOnChatListener != null) {
            mOnChatListener.onChatStatusChanged(channel.getConnectStatus());
        }
        return null;
    }

}
